﻿using System.Collections.Concurrent;
using Microsoft.Extensions.Caching.Memory;

namespace OpenAIProxy;

public interface IStorageService
{
    Task SaveRecordAsync(ChatRecord record);
    Task<IEnumerable<ChatRecord>> GetHistoryAsync();
}

public class PersistentStorage : IStorageService
{
    private readonly IFileStorage _fileStorage;
    private readonly MemoryCache _cache;
    private readonly ILogger<PersistentStorage> _logger;

    public PersistentStorage(IFileStorage fileStorage, ILogger<PersistentStorage> logger, MemoryCacheOptions cacheOptions = null)
    {
        _cache = new MemoryCache(cacheOptions ?? new MemoryCacheOptions());
        
        if (fileStorage == null) throw new ArgumentNullException(nameof(fileStorage));
        if (logger == null) throw new ArgumentNullException(nameof(logger));
    
        _fileStorage = fileStorage;
        _logger = logger;
    }

    public async Task SaveRecordAsync(ChatRecord record)
    {
        try
        {
            _cache.Set(record.Id, record, DateTimeOffset.Now.AddMinutes(30));
            
            await _fileStorage.SaveChatRecordAsync(record);
            await _fileStorage.LogInformationAsync($"记录已保存: {record.Id}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "存储记录失败");
            await _fileStorage.LogErrorAsync($"存储记录失败: {ex.Message}");
        }
    }

    public async Task<IEnumerable<ChatRecord>> GetHistoryAsync()
    {
        try
        {
            var records = new List<ChatRecord>();
            foreach (var item in _cache.Keys)
            {
                if (item is ChatRecord record)
                {
                    records.Add(record);
                }
            }
            await _fileStorage.LogInformationAsync($"获取历史记录，共{records.Count}条");
            return records;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取历史记录失败");
            await _fileStorage.LogErrorAsync($"获取历史记录失败: {ex.Message}");
            return Enumerable.Empty<ChatRecord>();
        }
    }
}
